package org.microservice.system.service.impl;

import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import org.microservice.common.bean.UserVo;
import org.microservice.common.util.R;
import org.microservice.common.util.constant.MqQueueConstant;
import org.microservice.redis.datascope.annotation.FilterDataScope;
import org.microservice.redis.util.RedisService;
import org.microservice.system.dao.SysUserDao;
import org.microservice.system.entity.SysUserDataScopeEntity;
import org.microservice.system.service.SysUserDataScopeService;
import org.microservice.system.service.SysUserRoleService;
import org.microservice.system.service.SysUserService;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

import java.io.Serializable;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * Created with IntelliJ IDEA.
 * User: 齐丹枫
 * Date: 2018/6/20
 * Time: 15:51
 * To change this template use File | Settings | File Templates.
 * Description:
 */
@Service
public class SysUserServiceImpl extends ServiceImpl<SysUserDao,UserVo> implements SysUserService{

    @Autowired
    private SysUserDao sysUserDao;

    @Autowired
    private SysUserRoleService sysUserRoleService;


    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Autowired
    private SysUserDataScopeService sysUserDataScopeService;

    @Autowired
    private RedisService redisService;

    @Override
    public UserVo getUserInfoByUserName(String userName) {
        return sysUserDao.getByUserName(userName);
    }

    @Override
    @FilterDataScope(ctrlTypes = {"dept"},columns = {"s1.department_id"})
    public List<UserVo> getUserListPage(Map<String, Object> params) {

        return sysUserDao.getUserListPage(params);
    }

    @Override
    @FilterDataScope(ctrlTypes = {"dept"},columns = {"s1.department_id"})
    public int getUserListPageTotal(Map<String, Object> params) {

        return sysUserDao.getUserListPageTotal(params);
    }

    @Override
    public R save(UserVo userVo) {

        /**
         * 加密用户的密码
         */
        BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();

        userVo.setPassword(bCryptPasswordEncoder.encode(userVo.getPassword()));


        /**
         * 保存用户信息
         */
        try{
            Integer insert = sysUserDao.insert(userVo);
        }catch (DuplicateKeyException e){
            return R.error("保存失败，用户名已经存在");
        }
        return R.ok();
    }

    @Override
    public R update(UserVo userVo) {


        try{
            sysUserDao.updateById(userVo);

        }catch (DuplicateKeyException e){
            return R.error("保存失败，用户名已经存在");
        }

        return R.ok();
    }

    @Override
    public R assignRoles(UserVo userVo) {

        sysUserRoleService.saveOrUpdate(userVo.getId(),userVo.getRoleIds());

        return R.ok();
    }

    @Override
    public List<Map<String, String>> getDepartmentLeadersByDepartmentId(Serializable departmentId) {
        List<Map<String, String>> userVos =sysUserDao.getDepartmentLeadersByDepartmentId(departmentId);
        return userVos;
    }

    @Override
    public R assignDataScope(String userName,int id, Map<String,List<Integer>> dataScopes) {
        sysUserDataScopeService.saveOrUpdate(id,dataScopes);
        rabbitTemplate.convertAndSend(MqQueueConstant.USER_DATA_SCOPE_CHANGE,userName);
        return R.ok();
    }



    @Override
    public Map<String, List<Integer>> getDataScopeByUserIdOrUserName(Integer id, String username) {
        List<SysUserDataScopeEntity> scopeEntities =  sysUserDao.getDataScopeByUserIdOrUserName(id,username);
        /**
         * 按照权限类型进行分组
         */
        HashMap<String, List<Integer>> map = new HashMap<>();
        if(scopeEntities != null && scopeEntities.size() > 0){
            Map<String, List<SysUserDataScopeEntity>> collect = scopeEntities.stream().collect(Collectors.groupingBy(SysUserDataScopeEntity::getCtrlType));
            Set<String> keySet = collect.keySet();
            for (String s :
                    keySet) {
                if(collect.get(s) != null && collect.get(s).size() > 0){
                    map.put(s,collect.get(s).stream().map(SysUserDataScopeEntity::getCtrlId).collect(Collectors.toList()));

                }
            }
        }


        return map;
    }


}
